package com.best.member.utils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;

import com.best.core.exception.CommonException;
import com.best.core.exception.CommonExceptionEnum;
import com.best.core.utils.RedisUtil;

/**
 * @ClassName: MultiTransactionManager
 * @Description: 多数据源事务管理
 * @Datetime: 2020/6/13 14:11
 * @Author: nike
 */
@Component
@Scope(ConfigurableListableBeanFactory.SCOPE_PROTOTYPE)
public class MultiTransactionManager {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;

    /**
     * 开启事务
     * 
     * @return
     */
    public TransactionStatus begin() {
        // 开启数据库事务
        TransactionStatus transaction =
                dataSourceTransactionManager.getTransaction(new DefaultTransactionAttribute());
        // 开启redis事务
        redisUtil.begin();

        return transaction;
    }

    /**
     * 提交事务
     * 
     * @param transactionStatus
     */
    public void commit(TransactionStatus transactionStatus) {
        if (null == transactionStatus) {
            throw new CommonException(CommonExceptionEnum.TRANSACTION_IS_ERROR,
                    "transactionStatus is null");
        }
        // 会同时提交redis和数据库事务
        dataSourceTransactionManager.commit(transactionStatus);
    }

    /**
     * 事务回滚
     * 
     * @param transactionStatus
     */
    public void rollback(TransactionStatus transactionStatus) {
        if (null == transactionStatus) {
            throw new CommonException(CommonExceptionEnum.TRANSACTION_IS_ERROR,
                    "transactionStatus is null");
        }
        // 回滚数据库事务
        dataSourceTransactionManager.rollback(transactionStatus);
        // 回滚redis事务
        redisUtil.rollback();
    }
}
